package demos;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Generator implements Runnable {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private volatile List<Integer> list = new ArrayList<>();

    @Override
    public void run() {
        int i = 0;
        while (!Thread.currentThread().interrupted()) {
            lock.lock();
            try {
                list.add(i);
                i++;
                condition.signalAll();
                TimeUnit.MILLISECONDS.sleep((int)(Math.random() * 2000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            Thread.yield();
        }
    }

    public Integer getNumber() {
        lock.lock();
        try {
            if(list.size() == 0)
                condition.await();
            return list.remove(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return -1;
    }
}
public class LockTest {
    public static void main(String[] args) {
        Generator g = new Generator();
        Thread t = new Thread(g);
        t.start();
        for(int i = 0; i < 20; i++)
            System.out.println(g.getNumber());
        t.interrupt();
    }
}
